﻿using System;
using System.Collections.Generic;
using Autodesk.Revit.DB;

namespace YJKCoordinate
{
	public class ThreeInputDataPacker : InputDataPackerBase
	{
		internal void SetEnd(bool ifEnd = true)
		{
			this.ifEnd = ifEnd;
			this.makeBoundryCurvePacker();
		}

		internal ThreeInputDataPacker(TwoInputDataPakcer inputOne, TwoInputDataPakcer inputTwo, XYZ realStartPoint = null, bool ifEnd = false)
		{
			this.ifEnd = ifEnd;
			this.realStartPoint = realStartPoint;
			if (!inputOne.GetPoint(1).IsAlmostEqualTo(inputTwo.GetPoint(0)))
			{
				throw new CornerMakerException(StaticRescource.StrNonContinuePoint);
			}
			this.useFamilyFileIndexs.Clear();
			this.useFamilyFileIndexs.Add(inputOne.GetFamilyFileIndex(0));
			this.useFamilyFileIndexs.Add(inputTwo.GetFamilyFileIndex(0));
			this.lstPoints.Clear();
			this.lstPoints.Add(inputOne.GetPoint(0));
			this.lstPoints.Add(inputOne.GetPoint(1));
			this.lstPoints.Add(inputTwo.GetPoint(1));
			this.driection.Clear();
			this.driection.Add(inputOne.GetPoint(1).Add(-inputOne.GetPoint(0)).Normalize());
			this.driection.Add(inputTwo.GetPoint(0).Add(-inputTwo.GetPoint(1)).Normalize());
			if (this.driection[0].IsAlmostEqualTo(this.driection[1]) || this.driection[0].IsAlmostEqualTo(-this.driection[1]))
			{
				this.ifIsCornerMid = false;
			}
			else
			{
				this.ifIsCornerMid = true;
			}
			this.lstTwoInputDataPackers.Clear();
			this.lstTwoInputDataPackers.Add(inputOne);
			this.lstTwoInputDataPackers.Add(inputTwo);
			this.lstInputParameter.Clear();
			this.lstInputParameter.Add(inputOne.GetParameters(1));
			this.lstInputParameter.Add(inputTwo.GetParameters(1));
			this.cornerKind = inputTwo.CornerKinde;
			switch (this.cornerKind)
			{
			case CornerKindEnum.RightAngle:
				this.boundartCurveMaker = RightAngleCornerCurveMaker.GetRightAngleCornerCurveMake();
				break;
			case CornerKindEnum.SingleChamfer:
				this.boundartCurveMaker = SingleChamferCornerCurveMaker.GetSingleChamferCornerCurveMaker();
				break;
			case CornerKindEnum.Chamfer:
				this.boundartCurveMaker = ChamferCornerCurveMaker.GetSingleChamferCornerCurveMaker();
				break;
			case CornerKindEnum.ArcAngle:
				this.boundartCurveMaker = ArcAngleCornerCurveMaker.GetSingleChamferCornerCurveMaker();
				break;
			default:
				this.boundartCurveMaker = RightAngleCornerCurveMaker.GetRightAngleCornerCurveMake();
				break;
			}
			this.makeBoundryCurvePacker();
			this.finalCheck();
		}

		internal XYZ GetEndPoint()
		{
			return this.realEndPoint;
		}

		public List<BoundryCurvePakcer> GetLstBoundryCurvePacker()
		{
			return this.lstBoundryCurvePacker;
		}

		public XYZ GetDriection(int index)
		{
			if (index == 0)
			{
				return this.driection[0];
			}
			return this.driection[1];
		}

		public TwoInputDataPakcer GetTwoInputData(int index)
		{
			if (index == 0)
			{
				return this.lstTwoInputDataPackers[0];
			}
			return this.lstTwoInputDataPackers[1];
		}

		private void makeBoundryCurvePacker()
		{
			this.lstBoundryCurvePacker.Clear();
			double[] valueParams = new double[]
			{
				this.lstTwoInputDataPackers[0].GetParameters(1)[UseParameterEnum.Depth],
				this.lstTwoInputDataPackers[0].GetParameters(1)[UseParameterEnum.Thickness],
				this.lstTwoInputDataPackers[0].GetParameters(1)[UseParameterEnum.FlateWidth],
				(double)this.lstTwoInputDataPackers[0].GetFamilyFileIndex(0),
				this.lstTwoInputDataPackers[0].GetParameters(1)[UseParameterEnum.OffsetValue]
			};
			double[] valueParams2 = new double[]
			{
				this.lstTwoInputDataPackers[1].GetParameters(1)[UseParameterEnum.Depth],
				this.lstTwoInputDataPackers[1].GetParameters(1)[UseParameterEnum.Thickness],
				this.lstTwoInputDataPackers[1].GetParameters(1)[UseParameterEnum.FlateWidth],
				(double)this.lstTwoInputDataPackers[1].GetFamilyFileIndex(0),
				this.lstTwoInputDataPackers[1].GetParameters(1)[UseParameterEnum.OffsetValue]
			};
			if (!this.ifIsCornerMid)
			{
				if (!this.ifEnd)
				{
					if (this.realStartPoint != null)
					{
						List<Curve> normalLineBoundryCurves = Utiltiy.GetNormalLineBoundryCurves(this.realStartPoint, this.lstPoints[1], this.lstTwoInputDataPackers[0].GetParameters(1));
						BoundryCurvePakcer item = new BoundryCurvePakcer(this.realStartPoint, this.lstPoints[1], normalLineBoundryCurves, false, valueParams);
						this.lstBoundryCurvePacker.Add(item);
					}
					else
					{
						List<Curve> normalLineBoundryCurves2 = Utiltiy.GetNormalLineBoundryCurves(this.lstPoints[0], this.lstPoints[1], this.lstTwoInputDataPackers[0].GetParameters(1));
						BoundryCurvePakcer item2 = new BoundryCurvePakcer(this.lstPoints[0], this.lstPoints[1], normalLineBoundryCurves2, false, valueParams);
						this.lstBoundryCurvePacker.Add(item2);
					}
					this.realEndPoint = this.lstPoints[1];
					return;
				}
				List<Curve> lstBoundryCurves;
				BoundryCurvePakcer item3;
				if (this.realStartPoint != null)
				{
					lstBoundryCurves = Utiltiy.GetNormalLineBoundryCurves(this.realStartPoint, this.lstPoints[1], this.lstTwoInputDataPackers[0].GetParameters(1));
					item3 = new BoundryCurvePakcer(this.realStartPoint, this.lstPoints[1], lstBoundryCurves, false, valueParams);
					this.lstBoundryCurvePacker.Add(item3);
				}
				else
				{
					lstBoundryCurves = Utiltiy.GetNormalLineBoundryCurves(this.lstPoints[0], this.lstPoints[1], this.lstTwoInputDataPackers[0].GetParameters(1));
					item3 = new BoundryCurvePakcer(this.lstPoints[0], this.lstPoints[1], lstBoundryCurves, false, valueParams);
					this.lstBoundryCurvePacker.Add(item3);
				}
				lstBoundryCurves = new List<Curve>();
				lstBoundryCurves = Utiltiy.GetNormalLineBoundryCurves(this.lstPoints[1], this.lstPoints[2], this.lstTwoInputDataPackers[1].GetParameters(1));
				item3 = new BoundryCurvePakcer(this.lstPoints[1], this.lstPoints[2], lstBoundryCurves, false, valueParams2);
				this.lstBoundryCurvePacker.Add(item3);
				this.realEndPoint = this.lstPoints[2];
				return;
			}
			else
			{
				XYZ xyz = null;
				XYZ xyz2 = null;
				List<Curve> lstBoundryCurves2 = new List<Curve>();
				new List<Curve>();
				lstBoundryCurves2 = this.boundartCurveMaker.GetCornerBoundryCurves(this, out xyz, out xyz2);
				BoundryCurvePakcer item4 = new BoundryCurvePakcer(xyz, xyz2, lstBoundryCurves2, true, valueParams);
				BoundryCurvePakcer item5;
				if (!this.ifEnd)
				{
					if (this.realStartPoint == null)
					{
						lstBoundryCurves2 = Utiltiy.GetNormalLineBoundryCurves(this.lstPoints[0], xyz, this.lstTwoInputDataPackers[0].GetParameters(1));
						item5 = new BoundryCurvePakcer(this.lstPoints[0], xyz, lstBoundryCurves2, false, valueParams);
					}
					else
					{
						lstBoundryCurves2 = Utiltiy.GetNormalLineBoundryCurves(this.realStartPoint, xyz, this.lstTwoInputDataPackers[0].GetParameters(1));
						item5 = new BoundryCurvePakcer(this.realStartPoint, xyz, lstBoundryCurves2, false, valueParams);
					}
					this.lstBoundryCurvePacker.Add(item5);
					this.lstBoundryCurvePacker.Add(item4);
					this.realEndPoint = xyz2;
					return;
				}
				List<Curve> lstBoundryCurves3 = new List<Curve>();
				if (this.realStartPoint == null)
				{
					lstBoundryCurves2 = Utiltiy.GetNormalLineBoundryCurves(this.lstPoints[0], xyz, this.lstTwoInputDataPackers[0].GetParameters(1));
					item5 = new BoundryCurvePakcer(this.lstPoints[0], xyz, lstBoundryCurves2, false, valueParams);
				}
				else
				{
					lstBoundryCurves2 = Utiltiy.GetNormalLineBoundryCurves(this.realStartPoint, xyz, this.lstTwoInputDataPackers[0].GetParameters(1));
					item5 = new BoundryCurvePakcer(this.realStartPoint, xyz, lstBoundryCurves2, false, valueParams);
				}
				lstBoundryCurves3 = Utiltiy.GetNormalLineBoundryCurves(xyz2, this.lstPoints[2], this.lstTwoInputDataPackers[1].GetParameters(1));
				BoundryCurvePakcer item6 = new BoundryCurvePakcer(xyz2, this.lstPoints[2], lstBoundryCurves3, false, valueParams2);
				this.lstBoundryCurvePacker.Add(item5);
				this.lstBoundryCurvePacker.Add(item4);
				this.lstBoundryCurvePacker.Add(item6);
				this.realEndPoint = this.lstPoints[2];
				return;
			}
		}

		private void finalCheck()
		{
			if (this.ifIsCornerMid)
			{
				if (this.realStartPoint == null)
				{
					if (this.lstBoundryCurvePacker[1].GetPoint(0).DistanceTo(this.lstPoints[1]) > this.lstPoints[0].DistanceTo(this.lstPoints[1]))
					{
						throw new CornerMakerException(StaticRescource.StrCornerOutSide);
					}
				}
				else if (this.lstBoundryCurvePacker[1].GetPoint(0).DistanceTo(this.lstPoints[1]) > this.realStartPoint.DistanceTo(this.lstPoints[1]))
				{
					throw new CornerMakerException(StaticRescource.StrCornerOutSide);
				}
				if (this.lstTwoInputDataPackers[1].GetPoint(1).DistanceTo(this.lstPoints[1]) > this.lstPoints[2].DistanceTo(this.lstPoints[1]))
				{
					throw new CornerMakerException(StaticRescource.StrCornerOutSide);
				}
			}
		}

		private bool ifIsCornerMid;

		private bool ifEnd;

		private XYZ realStartPoint;

		private XYZ realEndPoint;

		private List<XYZ> driection = new List<XYZ>();

		private List<TwoInputDataPakcer> lstTwoInputDataPackers = new List<TwoInputDataPakcer>();

		private IMakeCornerCurves boundartCurveMaker;

		private List<BoundryCurvePakcer> lstBoundryCurvePacker = new List<BoundryCurvePakcer>();
	}
}
